home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / ctlbre_1 / ctlbreak.ctl < prev    next >
Encoding:
Text File  |  1998-07-19  |  22.1 KB  |  675 lines

  1. VERSION 5.00
  2. Begin VB.UserControl ctlBreakout 
  3.    BorderStyle     =   1  'Fixed Single
  4.    ClientHeight    =   7380
  5.    ClientLeft      =   0
  6.    ClientTop       =   0
  7.    ClientWidth     =   9600
  8.    KeyPreview      =   -1  'True
  9.    ScaleHeight     =   492
  10.    ScaleMode       =   3  'Pixel
  11.    ScaleWidth      =   640
  12.    ToolboxBitmap   =   "ctlBreakout.ctx":0000
  13.    Begin VB.CommandButton cmdBall 
  14.       Caption         =   "Shoot Ball"
  15.       Height          =   495
  16.       Left            =   4440
  17.       TabIndex        =   9
  18.       Top             =   6720
  19.       Width           =   1095
  20.    End
  21.    Begin VB.CommandButton cmdNewGame 
  22.       Caption         =   "New Game"
  23.       Height          =   495
  24.       Left            =   8040
  25.       TabIndex        =   8
  26.       Top             =   6720
  27.       Width           =   1095
  28.    End
  29.    Begin VB.ComboBox cmbLevel 
  30.       Height          =   315
  31.       ItemData        =   "ctlBreakout.ctx":0312
  32.       Left            =   360
  33.       List            =   "ctlBreakout.ctx":0314
  34.       Style           =   2  'Dropdown List
  35.       TabIndex        =   7
  36.       Top             =   6720
  37.       Width           =   1455
  38.    End
  39.    Begin VB.CommandButton cmdHighScore 
  40.       Caption         =   "HighScore"
  41.       Height          =   375
  42.       Left            =   1920
  43.       TabIndex        =   6
  44.       Top             =   6720
  45.       Width           =   975
  46.    End
  47.    Begin VB.PictureBox picBlack 
  48.       Appearance      =   0  'Flat
  49.       AutoRedraw      =   -1  'True
  50.       BackColor       =   &H00000000&
  51.       FillStyle       =   0  'Solid
  52.       ForeColor       =   &H80000008&
  53.       Height          =   375
  54.       Left            =   360
  55.       ScaleHeight     =   345
  56.       ScaleWidth      =   1245
  57.       TabIndex        =   3
  58.       Top             =   5880
  59.       Width           =   1275
  60.       Visible         =   0   'False
  61.    End
  62.    Begin VB.PictureBox picField 
  63.       Appearance      =   0  'Flat
  64.       BackColor       =   &H00000000&
  65.       ClipControls    =   0   'False
  66.       ForeColor       =   &H80000008&
  67.       Height          =   5295
  68.       Left            =   240
  69.       ScaleHeight     =   351
  70.       ScaleMode       =   3  'Pixel
  71.       ScaleWidth      =   603
  72.       TabIndex        =   0
  73.       Top             =   480
  74.       Width           =   9075
  75.       Begin VB.PictureBox picPaddle 
  76.          Appearance      =   0  'Flat
  77.          AutoRedraw      =   -1  'True
  78.          AutoSize        =   -1  'True
  79.          BackColor       =   &H00000000&
  80.          BorderStyle     =   0  'None
  81.          FillColor       =   &H00FFFFFF&
  82.          FillStyle       =   0  'Solid
  83.          ForeColor       =   &H00FFFFFF&
  84.          Height          =   90
  85.          Left            =   4440
  86.          Picture         =   "ctlBreakout.ctx":0316
  87.          ScaleHeight     =   6
  88.          ScaleMode       =   3  'Pixel
  89.          ScaleWidth      =   30
  90.          TabIndex        =   2
  91.          Top             =   5040
  92.          Width           =   450
  93.       End
  94.       Begin VB.PictureBox picBall 
  95.          Appearance      =   0  'Flat
  96.          AutoRedraw      =   -1  'True
  97.          AutoSize        =   -1  'True
  98.          BackColor       =   &H80000005&
  99.          BorderStyle     =   0  'None
  100.          ForeColor       =   &H80000008&
  101.          Height          =   90
  102.          Left            =   3960
  103.          Picture         =   "ctlBreakout.ctx":037F
  104.          ScaleHeight     =   6
  105.          ScaleMode       =   3  'Pixel
  106.          ScaleWidth      =   6
  107.          TabIndex        =   1
  108.          Top             =   4560
  109.          Width           =   90
  110.          Visible         =   0   'False
  111.       End
  112.       Begin VB.Image imgBlock 
  113.          Appearance      =   0  'Flat
  114.          DragMode        =   1  'Automatic
  115.          Enabled         =   0   'False
  116.          Height          =   180
  117.          Index           =   0
  118.          Left            =   240
  119.          OLEDragMode     =   1  'Automatic
  120.          OLEDropMode     =   2  'Automatic
  121.          Picture         =   "ctlBreakout.ctx":03E1
  122.          Top             =   360
  123.          Width           =   360
  124.          Visible         =   0   'False
  125.       End
  126.    End
  127.    Begin VB.Label lblScore 
  128.       Caption         =   "Score: "
  129.       Height          =   255
  130.       Left            =   3840
  131.       TabIndex        =   5
  132.       Top             =   120
  133.       Width           =   1455
  134.    End
  135.    Begin VB.Label lblBallsLeft 
  136.       Caption         =   "Balls left: "
  137.       Height          =   255
  138.       Left            =   8040
  139.       TabIndex        =   4
  140.       Top             =   120
  141.       Width           =   1455
  142.    End
  143.    Begin VB.Image imgBlockColor 
  144.       Appearance      =   0  'Flat
  145.       DragMode        =   1  'Automatic
  146.       Enabled         =   0   'False
  147.       Height          =   180
  148.       Index           =   0
  149.       Left            =   1920
  150.       OLEDragMode     =   1  'Automatic
  151.       OLEDropMode     =   2  'Automatic
  152.       Picture         =   "ctlBreakout.ctx":0459
  153.       Top             =   5880
  154.       Width           =   360
  155.       Visible         =   0   'False
  156.    End
  157.    Begin VB.Image imgBlockColor 
  158.       Appearance      =   0  'Flat
  159.       DragMode        =   1  'Automatic
  160.       Enabled         =   0   'False
  161.       Height          =   180
  162.       Index           =   1
  163.       Left            =   2400
  164.       OLEDragMode     =   1  'Automatic
  165.       OLEDropMode     =   2  'Automatic
  166.       Picture         =   "ctlBreakout.ctx":04D1
  167.       Top             =   5880
  168.       Width           =   360
  169.       Visible         =   0   'False
  170.    End
  171.    Begin VB.Image imgBlockColor 
  172.       Appearance      =   0  'Flat
  173.       DragMode        =   1  'Automatic
  174.       Enabled         =   0   'False
  175.       Height          =   180
  176.       Index           =   2
  177.       Left            =   3000
  178.       OLEDragMode     =   1  'Automatic
  179.       OLEDropMode     =   2  'Automatic
  180.       Picture         =   "ctlBreakout.ctx":0549
  181.       Top             =   5880
  182.       Width           =   360
  183.       Visible         =   0   'False
  184.    End
  185. End
  186. Attribute VB_Name = "ctlBreakout"
  187. Attribute VB_GlobalNameSpace = False
  188. Attribute VB_Creatable = True
  189. Attribute VB_PredeclaredId = False
  190. Attribute VB_Exposed = True
  191. '-------------------------------------------------------------------------
  192. 'Author:    Anders Fransson
  193. 'Email:     anders.fransson@home.se
  194. 'Internet:  http://hem1.passagen.se/fylke
  195. 'Date:      98-07-10
  196. '-------------------------------------------------------------------------
  197.  
  198. Option Explicit
  199.  
  200. Private m_iXstep As Integer                 'Ball step in x-dir
  201. Private m_iYstep As Integer                 'Ball step in y-dir
  202. Private m_iKeyCode As Integer               'Left key = -1, Right Key = 1, Key up = 0
  203. Private m_iRows As Integer                  'No rows with blocks
  204. Private m_iBlockIndex As Integer            'Index of block (overlapped with ball)
  205. Private m_vLevel As Variant                 'String array with levels
  206. Private m_iLevel As Integer                 'Level (0-2)
  207. Private m_lScore As Long                    'Total score
  208. Private m_lLevelScore As Long               'Score at current level
  209. Private m_iNoBallsLeft As Integer
  210.  
  211. 'Sizes
  212. Private m_iBallLeft As Integer
  213. Private m_iBallTop As Integer
  214. Private m_iBallDiameter As Integer
  215. Private m_iBlockLeft As Integer
  216. Private m_iBlockTop As Integer
  217. Private m_iBlockHeight As Integer
  218. Private m_iBlockWidth As Integer
  219. Private m_iPaddleLeft As Integer
  220. Private m_iPaddleTop As Integer
  221. Private m_iPaddleHeight As Integer
  222. Private m_iPaddleWidth As Integer
  223. Private m_iFieldLeft As Integer
  224. Private m_iFieldWidth As Integer
  225.  
  226. 'Field size (ball diameter as unit)
  227. Private Const X_SIZE  As Integer = 104
  228. Private Const Y_SIZE  As Integer = 69
  229.  
  230. 'Blocks
  231. Private Const MAX_ROWS  As Integer = 24
  232. Private Const EMPTY_ROWS  As Integer = 3
  233. Private Const BLOCKS_IN_ROW  As Integer = 26
  234.  
  235. 'Ball
  236. Private Const MAX_BALLS  As Integer = 5
  237. Private Const TOP_LEFT As Integer = 0
  238. Private Const TOP_RIGHT As Integer = 1
  239. Private Const BOTTOM_LEFT As Integer = 2
  240. Private Const BOTTOM_RIGHT As Integer = 3
  241.  
  242. 'Key constants
  243. Private Const KEY_LEFT As Integer = -1
  244. Private Const KEY_RIGHT As Integer = 1
  245.  
  246. 'Paddle
  247. Private Const PADDLE_STEP As Integer = 4
  248.  
  249. 'Level (BallTimer interval)
  250. Private Const LEVEL_EASY As Integer = 16
  251. Private Const LEVEL_MEDIUM As Integer = 8
  252. Private Const LEVEL_HARD As Integer = 4
  253.  
  254. 'Text constants
  255. Private Const TEXT_HIGH_SCORE As String = "High Score"
  256. Private Const TEXT_INPUT_PLAYER As String = "Write your name!"
  257. Private Const TEXT_LEVEL As String = "Level"
  258. Private Const TEXT_PLAYER As String = "Player"
  259. Private Const TEXT_SCORE As String = "Score"
  260. Private Const TEXT_EASY As String = "Easy"
  261. Private Const TEXT_MEDIUM As String = "Medium"
  262. Private Const TEXT_HARD As String = "Hard"
  263. Private Const TEXT_BALLS_LEFT As String = "Balls left"
  264.  
  265. 'Registry constants
  266. Private Const TEXT_ANDERS_GAMES As String = "Anders Franssons Made In Home Games"
  267. Private Const TEXT_REGISTRY_PADDLE As String = "Breakout"
  268. Private Const TEXT_REGISTRY_PLAYER As String = "Player"
  269.  
  270. Private WithEvents BallTimer As ccrpTimer
  271. Attribute BallTimer.VB_VarHelpID = -1
  272. Private WithEvents PaddleTimer As ccrpTimer
  273. Attribute PaddleTimer.VB_VarHelpID = -1
  274.  
  275. Private Sub UserControl_Show()
  276.  
  277.     Dim i%
  278.  
  279.     'Create timer objects
  280.     Set BallTimer = New ccrpTimer
  281.     Set PaddleTimer = New ccrpTimer
  282.     
  283.     'Ball-timer properties
  284.     With BallTimer
  285.         .EventType = TimerPeriodic
  286.         .Stats.Frequency = 2
  287.     End With
  288.     
  289.     'Paddle-timer properties
  290.     With PaddleTimer
  291.         .EventType = TimerPeriodic
  292.         .Stats.Frequency = 2
  293.         .Enabled = True
  294.     End With
  295.     
  296.     'Load blocks
  297.     For i = 1 To BLOCKS_IN_ROW * MAX_ROWS + 1
  298.         Load imgBlock(i)
  299.     Next
  300.     
  301.     'Set size variables (use variables instead of properties = faster)
  302.     m_iBallDiameter = picBall.Width
  303.     m_iBlockHeight = imgBlock(0).Height
  304.     m_iBlockWidth = imgBlock(0).Width
  305.     m_iPaddleHeight = picPaddle.Height
  306.     m_iPaddleWidth = picPaddle.Width
  307.     m_iPaddleTop = Y_SIZE * m_iBallDiameter - 2 * m_iPaddleHeight
  308.  
  309.     'Start values
  310.     m_iFieldLeft = 4
  311.     m_iFieldWidth = X_SIZE * m_iBallDiameter + 2
  312.     picField.Move m_iFieldLeft, 20, m_iFieldWidth, Y_SIZE * m_iBallDiameter + 4
  313.     m_vLevel = Array(TEXT_EASY, TEXT_MEDIUM, TEXT_HARD)
  314.     lblScore.Move m_iFieldWidth / 2 - 30, 5
  315.     lblBallsLeft.Move m_iFieldWidth - 55, 5
  316.     
  317.     'Add combo box items
  318.      cmbLevel.AddItem TEXT_EASY
  319.      cmbLevel.AddItem TEXT_MEDIUM
  320.      cmbLevel.AddItem TEXT_HARD
  321.     
  322.     'Select medium level
  323.     cmbLevel.ListIndex = 1
  324.     
  325.     'Initialize random number generator
  326.     Randomize
  327.     
  328.     SetFocus
  329.  
  330.     NewGame
  331.  
  332. End Sub
  333.  
  334. Private Sub UserControl_KeyDown(KeyCode As Integer, Shift As Integer)
  335.  
  336.     'Update paddle direction
  337.     Select Case KeyCode
  338.         Case vbKeyLeft, vbKeyNumpad4: m_iKeyCode = KEY_LEFT
  339.         Case vbKeyRight, vbKeyNumpad6: m_iKeyCode = KEY_RIGHT
  340.         Case vbKeyReturn: If Not BallTimer.Enabled Then NewBall
  341.     End Select
  342.     
  343. End Sub
  344.  
  345. Private Sub UserControl_KeyUp(KeyCode As Integer, Shift As Integer)
  346.     
  347.     'Stop paddle
  348.     Select Case KeyCode
  349.         Case vbKeyLeft, vbKeyNumpad4: If m_iKeyCode = KEY_LEFT Then m_iKeyCode = 0
  350.         Case vbKeyRight, vbKeyNumpad6: If m_iKeyCode = KEY_RIGHT Then m_iKeyCode = 0
  351.     End Select
  352.     
  353. End Sub
  354.  
  355. Private Sub UserControl_Terminate()
  356.  
  357.     BallTimer.Enabled = False
  358.     PaddleTimer.Enabled = False
  359.     Set BallTimer = Nothing
  360.     Set PaddleTimer = Nothing
  361.  
  362. End Sub
  363.  
  364. Private Sub cmdHighScore_Click()
  365.     
  366.     Dim i%
  367.     Dim sHighScore As String, sTab As String
  368.     
  369.     sHighScore = TEXT_LEVEL & vbTab & vbTab & TEXT_SCORE & vbTab & vbTab & _
  370.         TEXT_PLAYER & vbNewLine & vbNewLine
  371.         
  372.     'Get high score from registry
  373.     For i = 0 To 2
  374.         sTab = vbTab
  375.         If Len(m_vLevel(i)) < 10 Then sTab = vbTab & vbTab
  376.         sHighScore = sHighScore & m_vLevel(i) & sTab & _
  377.             GetSetting(TEXT_ANDERS_GAMES, TEXT_REGISTRY_PADDLE, i, "-") & vbTab & vbTab & _
  378.             GetSetting(TEXT_ANDERS_GAMES, TEXT_REGISTRY_PADDLE, TEXT_REGISTRY_PLAYER & i, "-") & _
  379.             vbNewLine
  380.     Next
  381.  
  382.     'Show high score in msgbox
  383.     MsgBox sHighScore, vbOKOnly, TEXT_HIGH_SCORE
  384.  
  385. End Sub
  386.  
  387. Private Sub cmdBall_Click()
  388.     NewBall
  389. End Sub
  390.  
  391. Private Sub cmbLevel_Click()
  392.  
  393.     m_iLevel = cmbLevel.ListIndex
  394.     
  395.     Select Case cmbLevel.ListIndex
  396.         Case 0
  397.             BallTimer.Interval = LEVEL_EASY
  398.             PaddleTimer.Interval = LEVEL_EASY - 4
  399.         Case 1
  400.             BallTimer.Interval = LEVEL_MEDIUM
  401.             PaddleTimer.Interval = LEVEL_MEDIUM
  402.         Case 2
  403.             BallTimer.Interval = LEVEL_HARD
  404.             PaddleTimer.Interval = LEVEL_HARD
  405.     End Select
  406.     
  407.     lblScore = m_vLevel(m_iLevel) & ": " & m_lScore
  408.  
  409. End Sub
  410.  
  411. Private Sub cmdNewGame_Click()
  412.     NewGame
  413. End Sub
  414.  
  415. Private Sub PaddleTimer_Timer(ByVal Milliseconds As Long)
  416.  
  417.     'Update paddle position
  418.     If (m_iPaddleLeft > m_iFieldLeft And m_iKeyCode = KEY_LEFT) Or _
  419.         (m_iPaddleLeft + m_iPaddleWidth < m_iFieldLeft + m_iFieldWidth - 5 And _
  420.         m_iKeyCode = KEY_RIGHT) Then
  421.             m_iPaddleLeft = m_iPaddleLeft + m_iKeyCode * PADDLE_STEP
  422.             PlacePaddle m_iPaddleLeft - 2, m_iPaddleTop
  423.     End If
  424.     
  425.     'Update the paddle if the ball has hit it
  426.     If (m_iBallTop + 2 * m_iBallDiameter >= m_iPaddleTop) Then picPaddle.Refresh
  427.     
  428. End Sub
  429.  
  430. Private Sub BallTimer_Timer(ByVal Milliseconds As Long)
  431.     
  432.     Dim i%
  433.     
  434.     'Update ball position
  435.     m_iBallLeft = m_iBallLeft + m_iXstep
  436.     m_iBallTop = m_iBallTop + m_iYstep
  437.     
  438.     'Change the ball direction if a wall is hit
  439.     If m_iBallLeft <= 0 Then
  440.         m_iXstep = Abs(m_iXstep)
  441.         PlaySound App.Path & "\WallHit.wav"
  442.     ElseIf m_iBallLeft + m_iBallDiameter >= m_iFieldWidth Then
  443.         m_iXstep = -Abs(m_iXstep)
  444.         PlaySound App.Path & "\WallHit.wav"
  445.     ElseIf m_iBallTop <= 0 Then
  446.         m_iYstep = Abs(m_iYstep)
  447.         PlaySound App.Path & "\WallHit.wav"
  448.     End If
  449.     
  450.     'Check if the paddle is hit
  451.     If (m_iBallTop + m_iBallDiameter >= picPaddle.Top) Then
  452.         'Outside paddle
  453.         If Not ((m_iBallLeft + m_iBallDiameter > picPaddle.Left - Abs(m_iXstep)) And _
  454.             (m_iBallLeft < picPaddle.Left + m_iPaddleWidth + Abs(m_iXstep))) Then
  455.             BallTimer.Enabled = False
  456.             RemoveBall picBall.Left, picBall.Top
  457.             m_iNoBallsLeft = m_iNoBallsLeft - 1
  458.             m_iKeyCode = 0
  459.             lblBallsLeft = TEXT_BALLS_LEFT & ": " & m_iNoBallsLeft
  460.             picBall.Refresh
  461.             PlaySound App.Path & "\PaddleMiss.wav"
  462.             cmdBall.Enabled = True
  463.             If m_iNoBallsLeft = 0 Then
  464.                 'If high score
  465.                 If m_lScore > GetSetting(TEXT_ANDERS_GAMES, TEXT_REGISTRY_PADDLE, m_iLevel, 0) Then
  466.                     SaveSetting TEXT_ANDERS_GAMES, TEXT_REGISTRY_PADDLE, m_iLevel, m_lScore
  467.                     SaveSetting TEXT_ANDERS_GAMES, TEXT_REGISTRY_PADDLE, TEXT_REGISTRY_PLAYER & m_iLevel, _
  468.                         Left(Trim(InputBox(TEXT_INPUT_PLAYER, TEXT_HIGH_SCORE)), 20)
  469.                 End If
  470.                 cmdBall.Enabled = False
  471.             End If
  472.             Exit Sub
  473.         'At the very right edge
  474.         ElseIf (m_iBallLeft + m_iBallDiameter / 2 >= picPaddle.Left + m_iPaddleWidth) Then
  475.             If m_iXstep < 4 Then
  476.                 m_iXstep = Abs(m_iXstep) + 1
  477.             Else
  478.                 m_iXstep = Abs(m_iXstep)
  479.             End If
  480.         'At the very left edge
  481.         ElseIf (m_iBallLeft + m_iBallDiameter / 2 <= picPaddle.Left) Then
  482.             If m_iXstep > -4 Then
  483.                 m_iXstep = -Abs(m_iXstep) - 1
  484.             Else
  485.                 m_iXstep = -Abs(m_iXstep)
  486.             End If
  487.         'At the right edge
  488.         ElseIf (m_iBallLeft + m_iBallDiameter >= picPaddle.Left + m_iPaddleWidth) Then
  489.             m_iXstep = Abs(m_iXstep)
  490.         'At the left edge
  491.         ElseIf (m_iBallLeft <= picPaddle.Left) Then
  492.             m_iXstep = -Abs(m_iXstep)
  493.         End If
  494.         PlaySound App.Path & "\PaddleHit.wav"
  495.         m_iYstep = -5 + Abs(m_iXstep)
  496.     End If
  497.     
  498.     'Check the ball overlap any block (loop the corners of the ball)
  499.     For i = TOP_LEFT To BOTTOM_RIGHT
  500.  
  501.         'Calculate index for block at selected ball position
  502.         If i = TOP_LEFT Then
  503.             m_iBlockIndex = Int(m_iBallTop / m_iBlockHeight) * BLOCKS_IN_ROW + _
  504.                 Int(m_iBallLeft / m_iBlockWidth) - BLOCKS_IN_ROW * EMPTY_ROWS
  505.         ElseIf i = TOP_RIGHT Then
  506.             m_iBlockIndex = Int(m_iBallTop / m_iBlockHeight) * BLOCKS_IN_ROW + _
  507.                Int((m_iBallLeft + m_iBallDiameter) / m_iBlockWidth) - BLOCKS_IN_ROW * EMPTY_ROWS
  508.         ElseIf i = BOTTOM_LEFT Then
  509.             m_iBlockIndex = Int((m_iBallTop + m_iBallDiameter) / m_iBlockHeight) * BLOCKS_IN_ROW + _
  510.                 Int(m_iBallLeft / m_iBlockWidth) - BLOCKS_IN_ROW * EMPTY_ROWS
  511.         ElseIf i = BOTTOM_RIGHT Then
  512.             m_iBlockIndex = Int((m_iBallTop + m_iBallDiameter) / m_iBlockHeight) * BLOCKS_IN_ROW + _
  513.                Int((m_iBallLeft + m_iBallDiameter) / m_iBlockWidth) - BLOCKS_IN_ROW * EMPTY_ROWS
  514.         End If
  515.  
  516.         'Exit if not valid index
  517.         If (m_iBlockIndex < 0) Or (m_iBlockIndex > BLOCKS_IN_ROW * m_iRows) Then _
  518.             m_iBlockIndex = BLOCKS_IN_ROW * MAX_ROWS + 1
  519.  
  520.         'Set block variables
  521.         m_iBlockLeft = imgBlock(m_iBlockIndex).Left
  522.         m_iBlockTop = imgBlock(m_iBlockIndex).Top
  523.  
  524.         'If block is hit
  525.         If imgBlock(m_iBlockIndex).Visible And Abs(m_iBallLeft - m_iBlockLeft) <= m_iBlockWidth Then
  526.             'from above
  527.             If m_iYstep > 0 Then
  528.                 If m_iBallTop >= m_iBlockTop - 2 Then
  529.                     m_iXstep = -m_iXstep
  530.                 Else
  531.                     m_iYstep = -m_iYstep
  532.                 End If
  533.             'from below
  534.             Else
  535.                 If m_iBallTop + m_iBallDiameter <= m_iBlockTop + m_iBlockHeight + 2 Then
  536.                     m_iXstep = -m_iXstep
  537.                 Else
  538.                     m_iYstep = -m_iYstep
  539.                 End If
  540.             End If
  541.             imgBlock(m_iBlockIndex).Visible = False
  542.             m_lScore = m_lScore + m_iRows - m_iBlockIndex \ BLOCKS_IN_ROW
  543.             m_lLevelScore = m_lLevelScore + m_iRows - m_iBlockIndex \ BLOCKS_IN_ROW
  544.             lblScore = m_vLevel(m_iLevel) & ": " & m_lScore
  545.             PlaySound App.Path & "\BlockHit.wav"
  546.             If m_lLevelScore = BLOCKS_IN_ROW * m_iRows * (m_iRows + 1) / 2 Then NewLevel
  547.             Exit Sub
  548.         End If
  549.         
  550.     Next
  551.     
  552.     'Place the ball to the new position
  553.     PlaceBall m_iBallLeft, m_iBallTop
  554.  
  555. End Sub
  556.  
  557. Private Sub NewBall()
  558.  
  559.     Dim iSign%
  560.  
  561.     'Disable controls
  562.     cmdBall.Enabled = False
  563.     cmbLevel.Enabled = False
  564.     cmdHighScore.Enabled = False
  565.     
  566.     'Exit if there are no balls left
  567.     If m_iNoBallsLeft = 0 Then Exit Sub
  568.     
  569.     'Place ball in the middle of the paddle
  570.     m_iBallLeft = m_iPaddleLeft + m_iPaddleWidth / 2 - m_iBallDiameter / 2
  571.     m_iBallTop = picPaddle.Top - m_iBallDiameter - 2
  572.     PlaceBall m_iBallLeft, m_iBallTop
  573.     
  574.     'Select random ball direction (-2 to 2)
  575.     iSign = Sgn((2 * Rnd) - 1)
  576.     If iSign = 0 Then iSign = 1
  577.     m_iXstep = iSign * Int((2 * Rnd) + 1)
  578.     m_iYstep = -5 + Abs(m_iXstep)
  579.     
  580.     'Start moving the ball
  581.     BallTimer.Enabled = True
  582.  
  583. End Sub
  584.  
  585. Private Sub NewLevel()
  586.  
  587.     Dim i%, j%
  588.  
  589.     m_lLevelScore = 0
  590.  
  591.     'Stop moving the ball
  592.     BallTimer.Enabled = False
  593.     
  594.     'Change ball position to the middle of the paddle
  595.     m_iBallLeft = m_iPaddleLeft + m_iPaddleWidth / 2 - m_iBallDiameter / 2
  596.     m_iBallTop = picPaddle.Top - m_iBallDiameter - 2
  597.     PlaceBall m_iBallLeft, m_iBallTop
  598.     RemoveBall picBall.Left, picBall.Top
  599.     
  600.     'Place block
  601.     If m_iRows < MAX_ROWS Then m_iRows = m_iRows + 6
  602.     For i = 0 To m_iRows - 1
  603.         For j = 0 To BLOCKS_IN_ROW - 1
  604.             imgBlock((i * BLOCKS_IN_ROW) + j).Move _
  605.                 j * m_iBlockWidth, (i + EMPTY_ROWS) * m_iBlockHeight
  606.             If i < m_iRows - 2 Then _
  607.                 imgBlock((i * BLOCKS_IN_ROW) + j).Picture = imgBlockColor(i \ 2 Mod 3).Picture
  608.             imgBlock((i * BLOCKS_IN_ROW) + j).Visible = True
  609.         Next
  610.     Next
  611.     
  612. End Sub
  613.  
  614. Private Sub NewGame()
  615.  
  616.     'Place paddle in the middle
  617.     m_iPaddleLeft = Int(X_SIZE / 2) * m_iBallDiameter - 1
  618.     picPaddle.Move m_iPaddleLeft, m_iPaddleTop
  619.     PlacePaddle picPaddle.Left, picPaddle.Top
  620.     RemoveBall picBall.Left, picBall.Top
  621.     
  622.     'Start values
  623.     m_iRows = 0
  624.     m_lScore = 0
  625.     m_iNoBallsLeft = MAX_BALLS
  626.     lblScore = m_vLevel(m_iLevel) & ": " & m_lScore
  627.     lblBallsLeft = TEXT_BALLS_LEFT & ": " & m_iNoBallsLeft
  628.     
  629.     'Enable controls
  630.     cmbLevel.Enabled = True
  631.     cmdBall.Enabled = True
  632.     cmdHighScore.Enabled = True
  633.     NewLevel
  634.     
  635. End Sub
  636.  
  637. Private Function PlaceBall(ByVal lLeft As Long, ByVal lTop As Long) As Long
  638.     
  639.     'Place black picture over ball
  640.     BitBlt picField.hDC, picBall.Left, picBall.Top, m_iBallDiameter, m_iBallDiameter, _
  641.         picBlack.hDC, 0, 0, SRCCOPY
  642.     
  643.     'Update ball position
  644.     picBall.Move lLeft, lTop
  645.     
  646.     'Write ball
  647.     PlaceBall = BitBlt(picField.hDC, lLeft, lTop, m_iBallDiameter, m_iBallDiameter, _
  648.         picBall.hDC, 0, 0, SRCCOPY)
  649.  
  650. End Function
  651.  
  652. Private Function RemoveBall(ByVal lLeft As Long, ByVal lTop As Long) As Long
  653.     RemoveBall = BitBlt(picField.hDC, lLeft, lTop, m_iBallDiameter, m_iBallDiameter, _
  654.         picBlack.hDC, 0, 0, SRCCOPY)
  655. End Function
  656.  
  657. Private Function PlacePaddle(ByVal lLeft As Long, ByVal lTop As Long) As Long
  658.     
  659.     'Place black picture over paddle
  660.     BitBlt picField.hDC, picPaddle.Left, picPaddle.Top, m_iPaddleWidth, m_iPaddleHeight, _
  661.         picBlack.hDC, 0, 0, SRCCOPY
  662.     
  663.     'Update paddle position
  664.     picPaddle.Move lLeft, lTop
  665.     
  666.     'Write paddle
  667.     PlacePaddle = BitBlt(picField.hDC, lLeft, lTop, m_iPaddleWidth, m_iPaddleHeight, _
  668.         picPaddle.hDC, 0, 0, SRCCOPY)
  669.  
  670. End Function
  671.  
  672. Private Sub PlaySound(strSound As String)
  673.     sndPlaySound strSound, SND_ASYNC Or SND_NODEFAULT
  674. End Sub
  675.